Week 14 : Interface and Application programming
Objectives for Week 14
- Write an application that interfaces a user with an input and/or output device that I made
Rain game simulation using pygame
I decided try something simple just to understand how an interface works. One of my batchmates suggested trying out a python
Pygame is a cross-platform set of Python modules which is used to create video games. It consists of computer graphics and sound libraries designed to be used with the Python programming language.
I wanted to use the SAMD11 board created in the electronic design week
1. Program the board in Arduino IDE
#include <Arduino.h>
const int potPin = 14; // Potentiometer connected to Arduino analog pin A0
void setup() {
Serial.begin(9600);
}
void loop() {
int intensity = analogRead(potPin);
// intensity = map(intensity,0,1023,0,20);
Serial.println(intensity);
delay(100); // Adjust delay as needed
}
Setting up the Environment:
- Install Python and Pygame on your system.
- Ensure you have a SAMD11 board connected to your computer for serial communication.
-
Initializing Pygame:
-
Import the necessary libraries:
pygame
,serial
, andrandom
.
- Initialize Pygame and set up the game window and screen dimensions.
-
Import the necessary libraries:
-
Defining Colors and Raindrop Class:
- Define color constants for the raindrops and background.
-
Create a
Raindrop
class to represent individual raindrops on the screen. The class should have attributes like position, speed, and color, along with methods for falling and drawing.
-
Serial Communication Setup:
-
Specify the serial port (
COM21
in your case) and baud rate for communication with the SAMD11 board.
-
Create a serial object (
ser
) using theSerial
class from theserial
module.
-
Specify the serial port (
-
Game Loop:
-
Set up the main game loop (
while running:
) to handle game events and update the game state.
-
Use a clock object (
clock
) to control the frame rate.
-
Set up the main game loop (
-
Reading Potentiometer Values:
-
Read potentiometer values from the SAMD11 board via serial communication (
ser.readline().decode().strip()
).
-
Convert the received string to an integer (
pot_value
) and handle any potential value errors.
-
Read potentiometer values from the SAMD11 board via serial communication (
-
Mapping Potentiometer Values to Intensity:
-
Define a function (
map_value
) to map the potentiometer values to the desired rain intensity range (0-20 in the example).
-
Use this function to map the potentiometer value to the
rain_intensity
variable.
-
Define a function (
-
Updating Rain Intensity and Color:
-
Update the rain intensity (
rain_intensity
) and corresponding color based on the mapped potentiometer value.
- Adjust the color gradient based on different intensity ranges (e.g., blue to green, green to yellow, yellow to red).
-
Update the rain intensity (
-
Generating Raindrops:
- Create raindrops based on the rain intensity and color. Each raindrop should have random positions, speeds, and fall behavior.
-
Rendering and Displaying Raindrops:
-
Draw and update each raindrop in the
raindrops
list within the game loop.
-
Clear the screen with the background color (
WHITE
) before drawing raindrops.
-
Update the display using
pygame.display.flip()
to show the changes.
-
Draw and update each raindrop in the
-
Handling Game Events and Exit:
- Handle game events (e.g., quitting the game window) within the main game loop using Pygame's event system.
-
Use a variable (
running
) to control the game loop and exit gracefully when needed.
-
Cap Frame Rate:
-
Use
clock.tick(30)
to cap the frame rate at 30 frames per second, ensuring smooth gameplay.
-
Use
Python side
import pygame
import serial
import random
pygame.init()
# Screen dimensions
width, height = 800, 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Rain Game")
# Colors
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
RED = (255, 0, 0)
# Raindrop class
class Raindrop:
def __init__(self, x, y, speed, color):
self.x = x
self.y = y
self.speed = speed
self.color = color
def fall(self):
self.y += self.speed
if self.y > height:
self.y = 0
def draw(self, screen):
pygame.draw.line(screen, self.color, (self.x, self.y), (self.x, self.y + 10), 2)
# Serial communication with SAMD11
arduino_port = 'COM21' # Update with your SAMD11's port
arduino_baudrate = 9600
ser = serial.Serial(arduino_port, arduino_baudrate)
clock = pygame.time.Clock()
running = True
raindrops = []
rain_intensity = 0
prev_pot_value = -1 # Set an initial previous potentiometer value
# Function to map a value from one range to another
def map_value(value, from_low, from_high, to_low, to_high):
return int(to_low + (value - from_low) * (to_high - to_low) / (from_high - from_low))
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Read intensity data from SAMD11 (potentiometer value)
intensity_str = ser.readline().decode().strip()
try:
pot_value = int(intensity_str)
except ValueError:
pot_value = 0
# Map the potentiometer value to the desired intensity range
rain_intensity = map_value(pot_value, 0, 1023, 0, 1000) # Example mapping to a range of 0-20
colour_value = map_value(pot_value, 0, 1023, 0, 255) # Example mapping to a range of 0-255
# Update rain intensity and color if potentiometer value changes
if pot_value != prev_pot_value:
if pot_value >= 0:
if colour_value <= 255:
color = (0, colour_value, 255 - colour_value) # Blue to Green gradient
elif colour_value <= 511:
color = (colour_value - 256, 255, 0) # Green to Yellow gradient
else:
color = (255, 255 - (colour_value - 512), 0) # Yellow to Red gradient
prev_pot_value = pot_value
print(color)
# Clear the screen
screen.fill(WHITE)
# Generate raindrops based on rain intensity and color
raindrops = [] # Clear the raindrops list
for _ in range(rain_intensity):
x = random.randint(0, width)
y = random.randint(0, height)
speed = random.randint(5, 20)
raindrops.append(Raindrop(x, y, speed, color))
# Draw and update raindrops
for drop in raindrops:
drop.fall()
drop.draw(screen)
# Update display
pygame.display.flip()
# Cap frame rate
clock.tick(30)
pygame.quit()
I got the code from chatgpt
So my intent was to increase and decrease the intensity of raindrops according to the increase and decrease in the value of potentiometer
Here is how it looks like
MIT App inventor
I also tried using MIT app inventor a bit, but didn’t really finish the process.